package com.polaris.live.ui.live.widget.base

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.ViewConfiguration
import android.widget.FrameLayout
import androidx.viewpager.widget.VerticalViewPager
import androidx.viewpager.widget.ViewPager
import kotlin.math.abs

/**
 * 拖动view
 *
 * @author Created by lucas on 2023/11/8 09:32
 * @since 1.0.0
 */
class PagerDragView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs),
    ViewPager.OnPageChangeListener {

    private var mPager: LiveVerticalViewPager? = null
    private var mIsScrolling = false
    private var mAllowScroll = true
    private var mDisallowScroll = false

    private val mTouchSlop = ViewConfiguration.get(context).scaledTouchSlop

    private var mDownX = 0
    private var mDownY = 0
    private var mScrollState = VerticalViewPager.SCROLL_STATE_IDLE

    private var mOnPageChangeListener: ViewPager.OnPageChangeListener? = null
    private var mOnAllowScrollListener: OnAllowScrollListener? = null

    fun setPager(pager: LiveVerticalViewPager) {
        mPager = pager.also {
            it.setOnPageChangeListener(this)
        }
    }

    fun setOnPageChangeListener(listener: ViewPager.OnPageChangeListener?) {
        mOnPageChangeListener = listener
    }

    fun setAllowScroll(allowScroll: Boolean) {
        mAllowScroll = allowScroll
    }

    fun isDisallowInterceptTouchEvent(): Boolean {
        return mDisallowScroll
    }

    override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
        mDisallowScroll = disallowIntercept
        super.requestDisallowInterceptTouchEvent(disallowIntercept)
    }

    override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
        when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> mDisallowScroll = false
        }

        val pager = mPager ?: return super.dispatchTouchEvent(ev)

        if (mIsScrolling) {
            when (ev.actionMasked) {
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE -> mIsScrolling = false
            }
            return pager.onDispatchTouchEvent(ev)
        }

        val onAllowScrollListener = mOnAllowScrollListener
        if (onAllowScrollListener != null && !onAllowScrollListener.OnAllowScroll()
            || !mAllowScroll
            || mDisallowScroll
        ) {
            return super.dispatchTouchEvent(ev)
        }

        when (ev.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                mDownX = ev.x.toInt()
                mDownY = ev.y.toInt()

                if (mScrollState == VerticalViewPager.SCROLL_STATE_SETTLING) {
                    return startTouch(ev, pager)
                }
            }
            MotionEvent.ACTION_MOVE -> {
                val moveX = ev.x.toInt()
                val moveY = ev.y.toInt()

                val dx = mDownX - moveX
                val dy = mDownY - moveY

                if (abs(dx) > mTouchSlop || abs(dy) > mTouchSlop) {
                    return startTouch(ev, pager)
                }
            }
        }

        super.dispatchTouchEvent(ev)
        return true
    }

    private fun startTouch(ev: MotionEvent, pager: LiveVerticalViewPager): Boolean {
        mIsScrolling = true

        ev.action = MotionEvent.ACTION_CANCEL
        super.dispatchTouchEvent(ev)

        ev.action = MotionEvent.ACTION_DOWN
        pager.onDispatchTouchEvent(ev)
        ev.action = MotionEvent.ACTION_MOVE
        return pager.onDispatchTouchEvent(ev)
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        mOnPageChangeListener?.onPageScrolled(position, positionOffset, positionOffsetPixels)
    }

    override fun onPageSelected(position: Int) {
        mOnPageChangeListener?.onPageSelected(position)
    }

    override fun onPageScrollStateChanged(state: Int) {
        mScrollState = state
        mOnPageChangeListener?.onPageScrollStateChanged(if (mIsScrolling) VerticalViewPager.SCROLL_STATE_DRAGGING else state)
    }

    fun autoScrollToNextPage() {
        val pager = mPager ?: return
        val nextPage = pager.currentItem + 1
        pager.setCurrentItem(nextPage, true)
    }

    fun setOnAllowScrollListener(l: OnAllowScrollListener) {
        mOnAllowScrollListener = l
    }

    fun interface OnAllowScrollListener {

        fun OnAllowScroll(): Boolean
    }
}